package top.melody.ecommerce.webapps.www.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import top.melody.ecommerce.common.util.DateUtil;
import top.melody.ecommerce.common.util.JsonMapper;
import top.melody.ecommerce.common.util.StringUtil;
import top.melody.ecommerce.common.util.security.DES3;
import top.melody.ecommerce.platform.api.domain.account.Account;
import top.melody.ecommerce.platform.api.domain.account.AccountAddress;
import top.melody.ecommerce.platform.handler.enums.AccountType;
import top.melody.ecommerce.platform.handler.enums.ActStatus;
import top.melody.ecommerce.platform.handler.enums.GenderType;
import top.melody.ecommerce.platform.handler.enums.RegionLevel;
import top.melody.ecommerce.platform.handler.enums.ResultMsg;
import top.melody.ecommerce.platform.handler.enums.ValidStatus;
import top.melody.ecommerce.platform.props.GlobalConfig;
import top.melody.ecommerce.webapps.www.base.AssertContext;
import top.melody.ecommerce.webapps.www.base.Constant;
import top.melody.ecommerce.webapps.www.weblogic.AccountWeblogic;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @author: blentle
 * @group: rd
 * @createdate: 2016/11/11 9:55
 * @mail: blentle.huan.ren@gmail.com
 * @description:
 * @since:1.0
 */
@Controller
@RequestMapping("/account")
public class AccountController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(AccountController.class);
    @Resource
    private AccountWeblogic accountWeblogic;
    @Resource
    private ResourceBundleMessageSource i18nSource;
    @Resource
    private GlobalConfig globalConfig;

    @RequestMapping(value = "/sign/in", method = RequestMethod.GET)
    public ModelAndView signIn0(@RequestParam(value = "redirectUrl", required = false) String redirectUrl) {
        String logicViewName = "account/account-sign-in";
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("redirectUrl", redirectUrl);
        return new ModelAndView(logicViewName, paramMap);
    }

    @RequestMapping(value = "/sign/in", method = RequestMethod.POST)
    @ResponseBody
    public String signIn(@RequestParam("loginId") String loginId,
                         @RequestParam("password") String password,
                         @RequestParam("remember") boolean rememberMe,
                         @RequestParam(value = "redirectUrl", required = false) String redirectUrl,
                         HttpServletRequest request,
                         HttpServletResponse response) {
        ResultMsg resultMsg = new ResultMsg(ResultMsg.CODE_E, i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {
            Account account = accountWeblogic.getAccount(loginId);
            if (account == null) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_UNSIGN_UP_ERROR, new String[]{AssertContext.getContextPath(request)}, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            String pass = DES3.encode(password);
            if (!account.getAccountPassword().equals(pass)) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_SIGN_IN_PASS_INCORRECT_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            if (account.getValidStatus().equals(ValidStatus.LOCKED)) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_LOCKED_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            accountWeblogic.signInAccount(account, password, rememberMe, request, response);
            resultMsg.setMsg(null);
            resultMsg.setStatusCode(ResultMsg.CODE_S);
            resultMsg.setResult(redirectUrl);
        } catch (Exception e) {
            logger.error("login error...", e);
        }
        return JsonMapper.jsonMapper().toJson(resultMsg);
    }

    @RequestMapping(value = "/sign/up", method = RequestMethod.GET)
    public ModelAndView signUp0(@RequestParam(value = "redirectUrl", required = false) String redirectUrl) {
        String logicViewName = "account/account-sign-up";
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("redirectUrl", redirectUrl);
        return new ModelAndView(logicViewName, paramMap);
    }

    @RequestMapping(value = "/sign/up", method = RequestMethod.POST)
    @ResponseBody
    public String signUp(@RequestParam("mobile") String loginId,
                         @RequestParam("screenName") String screenName,
                         @RequestParam("password") String password,
                         @RequestParam("confpass") String confirmPassword,
                         @RequestParam("captcha") String smsCode,
                         @RequestParam("agreement") boolean agreement,
                         @RequestParam(value = "redirectUrl", required = false) String redirectUrl,
                         HttpServletRequest request) {
        ResultMsg resultMsg = new ResultMsg(ResultMsg.CODE_E, i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {
            if (!agreement) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_AGREEMENT_DISAGREE_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            if (!confirmPassword.equals(password)) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_PASS_CONFPASS_MATCH_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            String codeFromCache = AssertContext.getSmsCodeFromSession(request);
            if (StringUtil.isEmpty(codeFromCache)) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_SMS_CODE_EXPIRED_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            if (!codeFromCache.equals(smsCode)) {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_SMS_CODE_SIGN_UP_INCORRECT_ERROR, null, Locale.CHINA));
                return JsonMapper.jsonMapper().toJson(resultMsg);
            }
            Account account = new Account();
            account.setUserId(loginId);
            account.setScreenName(screenName);
            account.setAccountMobile(loginId);
            account.setAccountPassword(password);
            account.setAccountPic(globalConfig.getDefaultPortrait());
            account.setAccountType(AccountType.CONSUMER);
            account.setValidStatus(ValidStatus.VALID);
            account.setRemoveStatus(ActStatus.UNACT);
            account.setCreateDate(new Date());
            account.setUpdateDate(new Date());
            //注册完，自动登录
            accountWeblogic.signUpAccount(account, request);
            resultMsg.setStatusCode(ResultMsg.CODE_S);
            resultMsg.setMsg(null);
            resultMsg.setResult(redirectUrl);
        } catch (Exception e) {
            logger.error("sign up error", e);
        }
        return JsonMapper.jsonMapper().toJson(resultMsg);
    }

    @RequestMapping("/sign/out")
    public String signOut(HttpServletRequest request, HttpServletResponse response) {
        //clear session ,clear cookie....
        try {
            AssertContext.removeFromSession(Constant.SESSION_ACCOUNT_KEY, request);
            AssertContext.removeFromCookie(Constant.COOKIE_ACCOUNT_KEY, request, response);
        } catch (Exception e) {
            logger.error("sign out error", e);
        }
        return "redirect:/" + AssertContext.getContextPath(request);
    }

    @RequestMapping("/password/find")
    public String findPassword(HttpServletRequest request, HttpServletResponse response) {
        //clear session ,clear cookie....
        try {

        } catch (Exception e) {

        }
        return "redirect:/" + AssertContext.getContextPath(request);
    }

    @RequestMapping("/address/create")
    @ResponseBody
    public String createDeliverAddress(HttpServletRequest request,
                                       String realName,
                                       String province,
                                       String city,
                                       String district,
                                       String address,
                                       String mobile,
                                       String email) {
        ResultMsg resultMsg = new ResultMsg(ResultMsg.CODE_E, i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {

        } catch (Exception e) {
            logger.error("create delivery address error", e);
        }
        return JsonMapper.nonEmptyMapper().toJson(resultMsg);
    }

    @RequestMapping("/address/delete/{addressId}")
    @ResponseBody
    public String removeDeliverAddress(@PathVariable("addressId") int addressId, HttpServletRequest request) {
        ResultMsg resultMsg = new ResultMsg(ResultMsg.CODE_E, i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {

        } catch (Exception e) {
            logger.error("delete delivery address error", e);
        }
        return JsonMapper.nonEmptyMapper().toJson(resultMsg);
    }

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public ModelAndView info(HttpServletRequest request) {
        String logicViewName = "account/account-information";
        Map<String, Object> paramMap = new HashMap<String, Object>();
        try {
            Account account = AssertContext.getCurrentAccount(request).getAccount();
            paramMap.put("account", account);
            paramMap.put("genderList", GenderType.getAll());
        } catch (UnsupportedEncodingException e) {
            logger.error("get account info error", e);
        }

        return new ModelAndView(logicViewName, paramMap);
    }

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public String saveAccountInfo(@RequestParam(value = "accountId", required = true) Integer accountId,
                                  @RequestParam(value = "accountEmail", required = false) String accountEmail,
                                  @RequestParam(value = "accountRealName", required = false) String accountRealName,
                                  @RequestParam(value = "screenName", required = false) String screenName,
                                  @RequestParam(value = "gender", required = false) String gender,
                                  @RequestParam(value = "birthday", required = false) String birthday,
                                  @RequestParam(value = "provinceId", required = false) Integer provinceId,
                                  @RequestParam(value = "cityId", required = false) Integer cityId,
                                  @RequestParam(value = "memo", required = false) String memo,
                                  HttpServletRequest request,
                                  HttpServletResponse response) {
        ResultMsg resultMsg = new ResultMsg(i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {
            Account account = new Account();
            account.setAccountId(accountId);
            if (!StringUtil.isEmpty(accountEmail))
                account.setAccountEmail(accountEmail);
            if (!StringUtil.isEmpty(accountRealName))
                account.setAccountRealName(accountRealName);
            if (!StringUtil.isEmpty(screenName))
                account.setScreenName(screenName);
            if (!StringUtil.isEmpty(gender))
                account.setGender(GenderType.getByCode(gender));
            if (!StringUtil.isEmpty(birthday))
                account.setBirthday(DateUtil.formatStringToDate(birthday, DateUtil.DATE_FORMAT));
            if (provinceId != null)
                account.setProvinceId(provinceId);
            if (cityId != null)
                account.setCityId(cityId);
            if (!StringUtil.isEmpty(memo))
                account.setMemo(memo);
            account.setUpdateDate(new Date());
            accountWeblogic.modifyAccountInfo(account, request, response);
            resultMsg.setMsg(null);
            resultMsg.setStatusCode(ResultMsg.CODE_S);
        } catch (Exception e) {
            logger.error("occurred exception when save account information !", e);
        }
        return JsonMapper.jsonMapper().toJson(resultMsg);
    }

    @RequestMapping(value = "/password/modify/pre", method = RequestMethod.GET)
    public ModelAndView modifyAccountPasswordPre(HttpServletRequest request) {
        String logicViewName = "account/account-password-edit";
        return new ModelAndView(logicViewName);
    }

    @RequestMapping(value = "/password/modify", method = RequestMethod.POST)
    @ResponseBody
    public String modifyAccountPassword(@RequestParam(value = "oldPassword", required = true) String oldPassword,
                                        @RequestParam(value = "newPassword", required = true) String newPassword,
                                        @RequestParam(value = "confirmPassword", required = true) String confirmPassword,
                                        HttpServletRequest request,
                                        HttpServletResponse response) {
        ResultMsg resultMsg = new ResultMsg(i18nSource.getMessage(Constant.ERROR_OPERATE_FAILED, null, Locale.CHINA));
        try {
            Account account = AssertContext.getCurrentAccount(request).getAccount();
            if (DES3.encode(oldPassword).equals(account.getAccountPassword())) {
                if (newPassword.equals(confirmPassword)) {
                    account.setAccountPassword(DES3.encode(confirmPassword));
                    account.setUpdateDate(new Date());
                    accountWeblogic.modifyAccountInfo(account, request, response);
                    resultMsg.setMsg(null);
                    resultMsg.setStatusCode(ResultMsg.CODE_S);
                } else {
                    resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_SET_PASSWORD_CONFPASS_MATCH_ERROR, null, Locale.CHINA));
                    resultMsg.setStatusCode(ResultMsg.CODE_E);
                }
            } else {
                resultMsg.setMsg(i18nSource.getMessage(Constant.ERROR_ACCOUNT_SET_PASSWORD_OLDPASS_INCORRECT_ERROR, null, Locale.CHINA));
                resultMsg.setStatusCode(ResultMsg.CODE_E);
            }
        } catch (Exception e) {
            logger.error("occurred exception when modify account password !", e);
        }
        return JsonMapper.jsonMapper().toJson(resultMsg);
    }

    @RequestMapping(value = "/address/list", method = RequestMethod.GET)
    public ModelAndView findAccountAddressList(HttpServletRequest request) {
        String logicViewName = "account/account-address";
        Map<String, Object> paramMap = new HashMap<>();

        try {
            Account account = AssertContext.getCurrentAccount(request).getAccount();
            AccountAddress accountAddress = new AccountAddress();
            accountAddress.setAccountId(account.getAccountId());
            List<AccountAddress> accountAddressList = accountWeblogic.findAccountAddressList(accountAddress);
            paramMap.put("list", accountAddressList);
        } catch (Exception e) {
            logger.error("occurred exception when find account address !", e);
        }

        return new ModelAndView(logicViewName, paramMap);
    }

    @RequestMapping("/avatar/preset")
    public ModelAndView preModifyAvatar(HttpServletRequest request) {
        String logicViewName = "account-avatar-set";
        Map<String, Object> paraMap = new HashMap<String, Object>();
        try {
            Account account = accountWeblogic.getAccount(AssertContext.getCurrentAccount(request).getAccount().getUserId());
            String imageDomain = globalConfig.getImgDomain();
            paraMap.put("portrait", account.getAccountPic());
            paraMap.put("imageDomain",imageDomain);
        } catch (Exception e) {
            logicViewName = "common/500";
            logger.error("occurred exception when preset avatar", e);
        }
        return new ModelAndView(logicViewName, paraMap);
    }



}
